package com.chentianle.check_app_install

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.content.pm.ResolveInfo
import android.net.Uri
import android.os.Build
import android.util.Log
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result


class CheckAppInstallPlugin : FlutterPlugin, MethodCallHandler {
    private lateinit var channel: MethodChannel
    private var context: Context? = null

    override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
        channel = MethodChannel(flutterPluginBinding.binaryMessenger, "com.chentianle/check_app_install")
        channel.setMethodCallHandler(this)
        context = flutterPluginBinding.applicationContext
    }

    override fun onMethodCall(call: MethodCall, result: Result) {
        when (call.method) {
            "getPlatformVersion" -> {
                result.success("Android ${android.os.Build.VERSION.RELEASE}")
            }

            "checkIsInstallApp" -> {
                context?.let {
                    val packageName = call.argument<String?>("packageName")
                    if (packageName != null) {
                        val info = getAppPackageInfo(it, packageName)
                        if (info != null) {
                            result.success(true)
                            return
                        }
                    }
                }
                result.success(false)
            }

            "openOtherApp" -> {
                try {
                    context?.let {
                        val uri = call.argument<String?>("uri")
//                        val packageName = call.argument<String?>("packageName")
//                    val className = call.argument<String?>("className")
//                        if (packageName != null) {
//                            val info = getAppPackageInfo(it, packageName)
//                            if (info != null) {
                                val intent = Intent(Intent.ACTION_VIEW, Uri.parse(uri)).apply {
//                                addCategory(Intent.CATEGORY_LAUNCHER)
//                                component = ComponentName(packageName, className)
                                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                                }
                                it.startActivity(intent)
                                result.success(true)
//                            if (className != null) {
//                                val intent = Intent().apply {
//                                    addCategory(Intent.CATEGORY_LAUNCHER)
//                                    component = ComponentName(packageName, className)
//                                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
//                                }
//                                it.startActivity(intent)
//                                result.success(true)
//                            } else {
//                                val success = openOtherApp(it, packageName, info)
//                                result.success(success)
//                            }
//                            }
//                        }
                    }
                } catch (e: Exception) {
                    e.message?.let { Log.e("openOtherApp", it) }
                }
                result.success(false)
            }

            else -> {
                result.notImplemented()
            }
        }
    }

    override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
        channel.setMethodCallHandler(null)
    }

    private fun getAppPackageInfo(context: Context, packageName: String): PackageInfo? {
        try {
            return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                context.packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0))
            } else {
                context.packageManager.getPackageInfo(packageName, 0)
            }
        } catch (e: NameNotFoundException) {
            e.message?.let { Log.e("getAppPackageInfo ($packageName)", it) }
        }
        return null
    }

    private fun openOtherApp(context: Context, packageName: String, pi: PackageInfo): Boolean {
        var pkgName = packageName
        try {
            val resolveIntent = Intent(Intent.ACTION_MAIN, null)
            resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER)
            resolveIntent.setPackage(pi.packageName)
            val apps: List<ResolveInfo> = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                context.packageManager.queryIntentActivities(resolveIntent, PackageManager.ResolveInfoFlags.of(0))
            } else {
                context.packageManager.queryIntentActivities(resolveIntent, 0)
            }
            val ri = apps.iterator().next()
            pkgName = ri.activityInfo.packageName
            val className = ri.activityInfo.name
            val intent = Intent(Intent.ACTION_MAIN)
            intent.addCategory(Intent.CATEGORY_LAUNCHER)
            val cn = ComponentName(pkgName, className)
            intent.setComponent(cn)
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            context.startActivity(intent)
            return true
        } catch (e: Exception) {
            e.message?.let { Log.e("openOtherApp ($packageName)", it) }
        }
        return false
    }

}
